const express = require('express');
const http = require('http');
const { Server } = require('socket.io');
const cors = require('cors');
const helmet = require('helmet');
const compression = require('compression');
const morgan = require('morgan');
const path = require('path');
const fs = require('fs-extra');
require('dotenv').config();

const logger = require('./config/logger');
const { errorHandler, notFoundHandler } = require('./middleware/errorHandler');
const SocketManager = require('./socket/socketManager');
const batchWriteService = require('./services/batchWriteService');
const ftpServer = require('./services/ftpServer');

// 创建Express应用
const app = express();
const server = http.createServer(app);

// 设置服务器超时（24小时，支持大文件上传）
server.setTimeout(24 * 60 * 60 * 1000); // 24小时
server.keepAliveTimeout = 120000; // 2分钟
server.headersTimeout = 125000; // 稍大于keepAliveTimeout

// 🔥 配置Socket.IO服务器，支持持久连接
const io = new Server(server, {
  cors: {
    origin: process.env.CORS_ORIGIN || '*',
    methods: ['GET', 'POST'],
    credentials: true
  },
  // 🔥 传输方式配置
  transports: ['websocket', 'polling'],
  // 🔥 允许升级
  allowUpgrades: true,
  // 🔥 ping配置（与客户端一致）
  pingTimeout: 60000, // 60秒未收到pong则断开
  pingInterval: 25000, // 每25秒发送一次ping
  // 🔥 连接超时
  connectTimeout: 45000,
  // 🔥 最大HTTP缓冲区大小
  maxHttpBufferSize: 1e8, // 100MB
  // 🔥 cookie配置
  cookie: false,
  // 🔥 服务器配置
  serveClient: false,
  // 🔥 允许EIO3
  allowEIO3: true
});

// 确保必要的目录存在
const requiredDirs = [
  path.join(__dirname, '../uploads'),
  path.join(__dirname, '../logs')
];

requiredDirs.forEach(dir => {
  fs.ensureDirSync(dir);
});

// 中间件配置
// 配置 helmet，放宽 CSP 策略以允许前端连接
app.use(helmet({
  contentSecurityPolicy: {
    directives: {
      defaultSrc: ["'self'"],
      scriptSrc: ["'self'", "'unsafe-inline'", "'unsafe-eval'"],
      styleSrc: ["'self'", "'unsafe-inline'", "https:", "http:"],
      imgSrc: ["'self'", "data:", "https:", "http:", "blob:"],
      connectSrc: ["'self'", "ws:", "wss:", "http:", "https:"],
      fontSrc: ["'self'", "data:", "https:", "http:"],
      objectSrc: ["'none'"],
      mediaSrc: ["'self'", "https:", "http:"],
      frameSrc: ["'self'"]
    }
  },
  crossOriginEmbedderPolicy: false,
  crossOriginResourcePolicy: { policy: "cross-origin" }
})); // 安全头
app.use(compression()); // 响应压缩
app.use(cors({
  origin: '*',
  credentials: true,
  methods: ['GET', 'POST', 'PUT', 'DELETE', 'OPTIONS'],
  allowedHeaders: ['Content-Type', 'Authorization']
})); // 跨域
app.use(express.json({ limit: '50gb' })); // JSON解析（无限制）
app.use(express.urlencoded({ extended: true, limit: '50gb' })); // URL编码解析（无限制）
app.use(morgan('combined', { stream: { write: message => logger.info(message.trim()) } })); // 请求日志

// 静态文件服务
app.use('/uploads', express.static(path.join(__dirname, '../uploads')));

// API路由
app.use('/api/auth', require('./routes/auth'));
app.use('/api/users', require('./routes/user'));
app.use('/api/files', require('./routes/file'));
app.use('/api/upload', require('./routes/upload')); // 文件上传
app.use('/api/transfer', require('./routes/transfer'));
app.use('/api/transfers', require('./routes/transfer')); // 别名，供前端使用
app.use('/api/transfer-queue', require('./routes/transferQueue')); // 传输队列（仅保存完成/失败的任务）
app.use('/api/notifications', require('./routes/notification'));
app.use('/api/stats', require('./routes/stats'));
app.use('/api/logs', require('./routes/logs'));
app.use('/api/software', require('./routes/software'));
app.use('/api/share', require('./routes/share')); // 文件分享
app.use('/api/clients', require('./routes/client')); // 客户端监控

// 健康检查
app.get('/health', (req, res) => {
  res.json({
    success: true,
    message: '服务运行正常',
    timestamp: new Date().toISOString()
  });
});

// 404处理
app.use(notFoundHandler);

// 错误处理
app.use(errorHandler);

// 初始化WebSocket管理器
const socketManager = new SocketManager(io);

// 将socketManager附加到app，便于在其他地方使用
app.set('socketManager', socketManager);

// 连接FTP服务器和WebSocket管理器
ftpServer.setSocketManager(socketManager);

// 启动服务器
const PORT = process.env.PORT || 3000;

server.listen(PORT, async () => {
  console.log(`
╔═══════════════════════════════════════════════════════╗
║                                                       ║
║   🚀 文件同步器服务器已启动                            ║
║                                                       ║
║   HTTP端口: ${PORT}                                    ║
║   环境: ${process.env.NODE_ENV || 'development'}      ║
║   时间: ${new Date().toLocaleString()}                ║
║                                                       ║
╚═══════════════════════════════════════════════════════╝
  `);

  logger.info(`HTTP服务器启动在端口 ${PORT}`);
  
  // 启动FTP服务器
  try {
    await ftpServer.start();
  } catch (error) {
    logger.error('FTP服务器启动失败:', error);
  }
  
  // 🔥 启动客户端离线状态检测定时任务（每30秒检查一次）
  setInterval(async () => {
    try {
      const db = require('./config/database');
      const [result] = await db.query(
        `UPDATE clients 
         SET is_online = 0 
         WHERE last_heartbeat < DATE_SUB(NOW(), INTERVAL 30 SECOND) 
         AND is_online = 1`
      );
      
      if (result.affectedRows > 0) {
        logger.info(`🔄 自动更新离线状态: ${result.affectedRows} 个客户端已标记为离线`);
      }
    } catch (error) {
      logger.error('更新客户端离线状态失败:', error);
    }
  }, 30000); // 每30秒检查一次
  
  logger.info('✅ 客户端离线状态自动检测已启动（每30秒）');
});

// 优雅关闭
process.on('SIGTERM', async () => {
  logger.info('接收到 SIGTERM 信号，开始优雅关闭...');
  
  // 刷新所有缓冲区
  logger.info('正在刷新批量写入缓冲区...');
  await batchWriteService.flushAll();
  
  // 停止FTP服务器
  await ftpServer.stop();
  
  server.close(() => {
    logger.info('HTTP 服务器已关闭');
    process.exit(0);
  });
});

process.on('SIGINT', async () => {
  logger.info('接收到 SIGINT 信号，开始优雅关闭...');
  
  // 刷新所有缓冲区
  logger.info('正在刷新批量写入缓冲区...');
  await batchWriteService.flushAll();
  
  // 停止FTP服务器
  await ftpServer.stop();
  
  server.close(() => {
    logger.info('HTTP 服务器已关闭');
    process.exit(0);
  });
});

module.exports = app;
